home *** CD-ROM | disk | FTP | other *** search
GNU Info File | 1998-10-28 | 42.9 KB | 918 lines |
- This is Info file ../info/cl, produced by Makeinfo-1.64 from the input
- file cl.texi.
-
- This file documents the GNU Emacs Common Lisp emulation package.
-
- Copyright (C) 1993 Free Software Foundation, Inc.
-
- Permission is granted to make and distribute verbatim copies of this
- manual provided the copyright notice and this permission notice are
- preserved on all copies.
-
- Permission is granted to copy and distribute modified versions of
- this manual under the conditions for verbatim copying, provided also
- that the section entitled "GNU General Public License" is included
- exactly as in the original, and provided that the entire resulting
- derived work is distributed under the terms of a permission notice
- identical to this one.
-
- Permission is granted to copy and distribute translations of this
- manual into another language, under the above conditions for modified
- versions, except that the section entitled "GNU General Public License"
- may be included in a translation approved by the author instead of in
- the original English.
-
- File: cl, Node: Structures, Next: Assertions, Prev: Hash Tables, Up: Top
-
- Structures
- **********
-
- The Common Lisp "structure" mechanism provides a general way to define
- data types similar to C's `struct' types. A structure is a Lisp object
- containing some number of "slots", each of which can hold any Lisp data
- object. Functions are provided for accessing and setting the slots,
- creating or copying structure objects, and recognizing objects of a
- particular structure type.
-
- In true Common Lisp, each structure type is a new type distinct from
- all existing Lisp types. Since the underlying Emacs Lisp system
- provides no way to create new distinct types, this package implements
- structures as vectors (or lists upon request) with a special "tag"
- symbol to identify them.
-
- - Special Form: defstruct NAME SLOTS...
- The `defstruct' form defines a new structure type called NAME,
- with the specified SLOTS. (The SLOTS may begin with a string
- which documents the structure type.) In the simplest case, NAME
- and each of the SLOTS are symbols. For example,
-
- (defstruct person name age sex)
-
- defines a struct type called `person' which contains three slots.
- Given a `person' object P, you can access those slots by calling
- `(person-name P)', `(person-age P)', and `(person-sex P)'. You
- can also change these slots by using `setf' on any of these place
- forms:
-
- (incf (person-age birthday-boy))
-
- You can create a new `person' by calling `make-person', which
- takes keyword arguments `:name', `:age', and `:sex' to specify the
- initial values of these slots in the new object. (Omitting any of
- these arguments leaves the corresponding slot "undefined,"
- according to the Common Lisp standard; in Emacs Lisp, such
- uninitialized slots are filled with `nil'.)
-
- Given a `person', `(copy-person P)' makes a new object of the same
- type whose slots are `eq' to those of P.
-
- Given any Lisp object X, `(person-p X)' returns true if X looks
- like a `person', false otherwise. (Again, in Common Lisp this
- predicate would be exact; in Emacs Lisp the best it can do is
- verify that X is a vector of the correct length which starts with
- the correct tag symbol.)
-
- Accessors like `person-name' normally check their arguments
- (effectively using `person-p') and signal an error if the argument
- is the wrong type. This check is affected by `(optimize (safety
- ...))' declarations. Safety level 1, the default, uses a somewhat
- optimized check that will detect all incorrect arguments, but may
- use an uninformative error message (e.g., "expected a vector"
- instead of "expected a `person'"). Safety level 0 omits all
- checks except as provided by the underlying `aref' call; safety
- levels 2 and 3 do rigorous checking that will always print a
- descriptive error message for incorrect inputs. *Note
- Declarations::.
-
- (setq dave (make-person :name "Dave" :sex 'male))
- => [cl-struct-person "Dave" nil male]
- (setq other (copy-person dave))
- => [cl-struct-person "Dave" nil male]
- (eq dave other)
- => nil
- (eq (person-name dave) (person-name other))
- => t
- (person-p dave)
- => t
- (person-p [1 2 3 4])
- => nil
- (person-p "Bogus")
- => nil
- (person-p '[cl-struct-person counterfeit person object])
- => t
-
- In general, NAME is either a name symbol or a list of a name
- symbol followed by any number of "struct options"; each SLOT is
- either a slot symbol or a list of the form `(SLOT-NAME
- DEFAULT-VALUE SLOT-OPTIONS...)'. The DEFAULT-VALUE is a Lisp form
- which is evaluated any time an instance of the structure type is
- created without specifying that slot's value.
-
- Common Lisp defines several slot options, but the only one
- implemented in this package is `:read-only'. A non-`nil' value
- for this option means the slot should not be `setf'-able; the
- slot's value is determined when the object is created and does not
- change afterward.
-
- (defstruct person
- (name nil :read-only t)
- age
- (sex 'unknown))
-
- Any slot options other than `:read-only' are ignored.
-
- For obscure historical reasons, structure options take a different
- form than slot options. A structure option is either a keyword
- symbol, or a list beginning with a keyword symbol possibly followed
- by arguments. (By contrast, slot options are key-value pairs not
- enclosed in lists.)
-
- (defstruct (person (:constructor create-person)
- (:type list)
- :named)
- name age sex)
-
- The following structure options are recognized.
-
- `:conc-name'
- The argument is a symbol whose print name is used as the
- prefix for the names of slot accessor functions. The default
- is the name of the struct type followed by a hyphen. The
- option `(:conc-name p-)' would change this prefix to `p-'.
- Specifying `nil' as an argument means no prefix, so that the
- slot names themselves are used to name the accessor functions.
-
- `:constructor'
- In the simple case, this option takes one argument which is an
- alternate name to use for the constructor function. The
- default is `make-NAME', e.g., `make-person'. The above
- example changes this to `create-person'. Specifying `nil' as
- an argument means that no standard constructor should be
- generated at all.
-
- In the full form of this option, the constructor name is
- followed by an arbitrary argument list. *Note Program
- Structure::, for a description of the format of Common Lisp
- argument lists. All options, such as `&rest' and `&key', are
- supported. The argument names should match the slot names;
- each slot is initialized from the corresponding argument.
- Slots whose names do not appear in the argument list are
- initialized based on the DEFAULT-VALUE in their slot
- descriptor. Also, `&optional' and `&key' arguments which
- don't specify defaults take their defaults from the slot
- descriptor. It is legal to include arguments which don't
- correspond to slot names; these are useful if they are
- referred to in the defaults for optional, keyword, or `&aux'
- arguments which *do* correspond to slots.
-
- You can specify any number of full-format `:constructor'
- options on a structure. The default constructor is still
- generated as well unless you disable it with a simple-format
- `:constructor' option.
-
- (defstruct
- (person
- (:constructor nil) ; no default constructor
- (:constructor new-person (name sex &optional (age 0)))
- (:constructor new-hound (&key (name "Rover")
- (dog-years 0)
- &aux (age (* 7 dog-years))
- (sex 'canine))))
- name age sex)
-
- The first constructor here takes its arguments positionally
- rather than by keyword. (In official Common Lisp
- terminology, constructors that work By Order of Arguments
- instead of by keyword are called "BOA constructors." No, I'm
- not making this up.) For example, `(new-person "Jane"
- 'female)' generates a person whose slots are `"Jane"', 0, and
- `female', respectively.
-
- The second constructor takes two keyword arguments, `:name',
- which initializes the `name' slot and defaults to `"Rover"',
- and `:dog-years', which does not itself correspond to a slot
- but which is used to initialize the `age' slot. The `sex'
- slot is forced to the symbol `canine' with no syntax for
- overriding it.
-
- `:copier'
- The argument is an alternate name for the copier function for
- this type. The default is `copy-NAME'. `nil' means not to
- generate a copier function. (In this implementation, all
- copier functions are simply synonyms for `copy-sequence'.)
-
- `:predicate'
- The argument is an alternate name for the predicate which
- recognizes objects of this type. The default is `NAME-p'.
- `nil' means not to generate a predicate function. (If the
- `:type' option is used without the `:named' option, no
- predicate is ever generated.)
-
- In true Common Lisp, `typep' is always able to recognize a
- structure object even if `:predicate' was used. In this
- package, `typep' simply looks for a function called
- `TYPENAME-p', so it will work for structure types only if
- they used the default predicate name.
-
- `:include'
- This option implements a very limited form of C++-style
- inheritance. The argument is the name of another structure
- type previously created with `defstruct'. The effect is to
- cause the new structure type to inherit all of the included
- structure's slots (plus, of course, any new slots described
- by this struct's slot descriptors). The new structure is
- considered a "specialization" of the included one. In fact,
- the predicate and slot accessors for the included type will
- also accept objects of the new type.
-
- If there are extra arguments to the `:include' option after
- the included-structure name, these options are treated as
- replacement slot descriptors for slots in the included
- structure, possibly with modified default values. Borrowing
- an example from Steele:
-
- (defstruct person name (age 0) sex)
- => person
- (defstruct (astronaut (:include person (age 45)))
- helmet-size
- (favorite-beverage 'tang))
- => astronaut
-
- (setq joe (make-person :name "Joe"))
- => [cl-struct-person "Joe" 0 nil]
- (setq buzz (make-astronaut :name "Buzz"))
- => [cl-struct-astronaut "Buzz" 45 nil nil tang]
-
- (list (person-p joe) (person-p buzz))
- => (t t)
- (list (astronaut-p joe) (astronaut-p buzz))
- => (nil t)
-
- (person-name buzz)
- => "Buzz"
- (astronaut-name joe)
- => error: "astronaut-name accessing a non-astronaut"
-
- Thus, if `astronaut' is a specialization of `person', then
- every `astronaut' is also a `person' (but not the other way
- around). Every `astronaut' includes all the slots of a
- `person', plus extra slots that are specific to astronauts.
- Operations that work on people (like `person-name') work on
- astronauts just like other people.
-
- `:print-function'
- In full Common Lisp, this option allows you to specify a
- function which is called to print an instance of the
- structure type. The Emacs Lisp system offers no hooks into
- the Lisp printer which would allow for such a feature, so
- this package simply ignores `:print-function'.
-
- `:type'
- The argument should be one of the symbols `vector' or `list'.
- This tells which underlying Lisp data type should be used to
- implement the new structure type. Vectors are used by
- default, but `(:type list)' will cause structure objects to
- be stored as lists instead.
-
- The vector representation for structure objects has the
- advantage that all structure slots can be accessed quickly,
- although creating vectors is a bit slower in Emacs Lisp.
- Lists are easier to create, but take a relatively long time
- accessing the later slots.
-
- `:named'
- This option, which takes no arguments, causes a
- characteristic "tag" symbol to be stored at the front of the
- structure object. Using `:type' without also using `:named'
- will result in a structure type stored as plain vectors or
- lists with no identifying features.
-
- The default, if you don't specify `:type' explicitly, is to
- use named vectors. Therefore, `:named' is only useful in
- conjunction with `:type'.
-
- (defstruct (person1) name age sex)
- (defstruct (person2 (:type list) :named) name age sex)
- (defstruct (person3 (:type list)) name age sex)
-
- (setq p1 (make-person1))
- => [cl-struct-person1 nil nil nil]
- (setq p2 (make-person2))
- => (person2 nil nil nil)
- (setq p3 (make-person3))
- => (nil nil nil)
-
- (person1-p p1)
- => t
- (person2-p p2)
- => t
- (person3-p p3)
- => error: function person3-p undefined
-
- Since unnamed structures don't have tags, `defstruct' is not
- able to make a useful predicate for recognizing them. Also,
- accessors like `person3-name' will be generated but they will
- not be able to do any type checking. The `person3-name'
- function, for example, will simply be a synonym for `car' in
- this case. By contrast, `person2-name' is able to verify
- that its argument is indeed a `person2' object before
- proceeding.
-
- `:initial-offset'
- The argument must be a nonnegative integer. It specifies a
- number of slots to be left "empty" at the front of the
- structure. If the structure is named, the tag appears at the
- specified position in the list or vector; otherwise, the first
- slot appears at that position. Earlier positions are filled
- with `nil' by the constructors and ignored otherwise. If the
- type `:include's another type, then `:initial-offset'
- specifies a number of slots to be skipped between the last
- slot of the included type and the first new slot.
-
- Except as noted, the `defstruct' facility of this package is
- entirely compatible with that of Common Lisp.
-
- File: cl, Node: Assertions, Next: Efficiency Concerns, Prev: Structures, Up: Top
-
- Assertions and Errors
- *********************
-
- This section describes two macros that test "assertions", i.e.,
- conditions which must be true if the program is operating correctly.
- Assertions never add to the behavior of a Lisp program; they simply
- make "sanity checks" to make sure everything is as it should be.
-
- If the optimization property `speed' has been set to 3, and `safety'
- is less than 3, then the byte-compiler will optimize away the following
- assertions. Because assertions might be optimized away, it is a bad
- idea for them to include side-effects.
-
- - Special Form: assert TEST-FORM [SHOW-ARGS STRING ARGS...]
- This form verifies that TEST-FORM is true (i.e., evaluates to a
- non-`nil' value). If so, it returns `nil'. If the test is not
- satisfied, `assert' signals an error.
-
- A default error message will be supplied which includes TEST-FORM.
- You can specify a different error message by including a STRING
- argument plus optional extra arguments. Those arguments are simply
- passed to `error' to signal the error.
-
- If the optional second argument SHOW-ARGS is `t' instead of `nil',
- then the error message (with or without STRING) will also include
- all non-constant arguments of the top-level FORM. For example:
-
- (assert (> x 10) t "x is too small: %d")
-
- This usage of SHOW-ARGS is an extension to Common Lisp. In true
- Common Lisp, the second argument gives a list of PLACES which can
- be `setf''d by the user before continuing from the error. Since
- Emacs Lisp does not support continuable errors, it makes no sense
- to specify PLACES.
-
- - Special Form: check-type FORM TYPE [STRING]
- This form verifies that FORM evaluates to a value of type TYPE.
- If so, it returns `nil'. If not, `check-type' signals a
- `wrong-type-argument' error. The default error message lists the
- erroneous value along with TYPE and FORM themselves. If STRING is
- specified, it is included in the error message in place of TYPE.
- For example:
-
- (check-type x (integer 1 *) "a positive integer")
-
- *Note Type Predicates::, for a description of the type specifiers
- that may be used for TYPE.
-
- Note that in Common Lisp, the first argument to `check-type' must
- be a PLACE suitable for use by `setf', because `check-type'
- signals a continuable error that allows the user to modify PLACE.
-
- The following error-related macro is also defined:
-
- - Special Form: ignore-errors FORMS...
- This executes FORMS exactly like a `progn', except that errors are
- ignored during the FORMS. More precisely, if an error is signaled
- then `ignore-errors' immediately aborts execution of the FORMS and
- returns `nil'. If the FORMS complete successfully, `ignore-errors'
- returns the result of the last FORM.
-
- File: cl, Node: Efficiency Concerns, Next: Common Lisp Compatibility, Prev: Assertions, Up: Top
-
- Efficiency Concerns
- *******************
-
- Macros
- ======
-
- Many of the advanced features of this package, such as `defun*',
- `loop', and `setf', are implemented as Lisp macros. In byte-compiled
- code, these complex notations will be expanded into equivalent Lisp
- code which is simple and efficient. For example, the forms
-
- (incf i n)
- (push x (car p))
-
- are expanded at compile-time to the Lisp forms
-
- (setq i (+ i n))
- (setcar p (cons x (car p)))
-
- which are the most efficient ways of doing these respective operations
- in Lisp. Thus, there is no performance penalty for using the more
- readable `incf' and `push' forms in your compiled code.
-
- *Interpreted* code, on the other hand, must expand these macros
- every time they are executed. For this reason it is strongly
- recommended that code making heavy use of macros be compiled. (The
- features labeled "Special Form" instead of "Function" in this manual
- are macros.) A loop using `incf' a hundred times will execute
- considerably faster if compiled, and will also garbage-collect less
- because the macro expansion will not have to be generated, used, and
- thrown away a hundred times.
-
- You can find out how a macro expands by using the `cl-prettyexpand'
- function.
-
- - Function: cl-prettyexpand FORM &optional FULL
- This function takes a single Lisp form as an argument and inserts
- a nicely formatted copy of it in the current buffer (which must be
- in Lisp mode so that indentation works properly). It also expands
- all Lisp macros which appear in the form. The easiest way to use
- this function is to go to the `*scratch*' buffer and type, say,
-
- (cl-prettyexpand '(loop for x below 10 collect x))
-
- and type `C-x C-e' immediately after the closing parenthesis; the
- expansion
-
- (block nil
- (let* ((x 0)
- (G1004 nil))
- (while (< x 10)
- (setq G1004 (cons x G1004))
- (setq x (+ x 1)))
- (nreverse G1004)))
-
- will be inserted into the buffer. (The `block' macro is expanded
- differently in the interpreter and compiler, so `cl-prettyexpand'
- just leaves it alone. The temporary variable `G1004' was created
- by `gensym'.)
-
- If the optional argument FULL is true, then *all* macros are
- expanded, including `block', `eval-when', and compiler macros.
- Expansion is done as if FORM were a top-level form in a file being
- compiled. For example,
-
- (cl-prettyexpand '(pushnew 'x list))
- -| (setq list (adjoin 'x list))
- (cl-prettyexpand '(pushnew 'x list) t)
- -| (setq list (if (memq 'x list) list (cons 'x list)))
- (cl-prettyexpand '(caddr (member* 'a list)) t)
- -| (car (cdr (cdr (memq 'a list))))
-
- Note that `adjoin', `caddr', and `member*' all have built-in
- compiler macros to optimize them in common cases.
-
-
- Error Checking
- ==============
-
- Common Lisp compliance has in general not been sacrificed for the sake
- of efficiency. A few exceptions have been made for cases where
- substantial gains were possible at the expense of marginal
- incompatibility. One example is the use of `memq' (which is treated
- very efficiently by the byte-compiler) to scan for keyword arguments;
- this can become confused in rare cases when keyword symbols are used as
- both keywords and data values at once. This is extremely unlikely to
- occur in practical code, and the use of `memq' allows functions with
- keyword arguments to be nearly as fast as functions that use
- `&optional' arguments.
-
- The Common Lisp standard (as embodied in Steele's book) uses the
- phrase "it is an error if" to indicate a situation which is not
- supposed to arise in complying programs; implementations are strongly
- encouraged but not required to signal an error in these situations.
- This package sometimes omits such error checking in the interest of
- compactness and efficiency. For example, `do' variable specifiers are
- supposed to be lists of one, two, or three forms; extra forms are
- ignored by this package rather than signaling a syntax error. The
- `endp' function is simply a synonym for `null' in this package.
- Functions taking keyword arguments will accept an odd number of
- arguments, treating the trailing keyword as if it were followed by the
- value `nil'.
-
- Argument lists (as processed by `defun*' and friends) *are* checked
- rigorously except for the minor point just mentioned; in particular,
- keyword arguments are checked for validity, and `&allow-other-keys' and
- `:allow-other-keys' are fully implemented. Keyword validity checking
- is slightly time consuming (though not too bad in byte-compiled code);
- you can use `&allow-other-keys' to omit this check. Functions defined
- in this package such as `find' and `member*' do check their keyword
- arguments for validity.
-
-
- Optimizing Compiler
- ===================
-
- The byte-compiler that comes with Emacs 18 normally fails to expand
- macros that appear in top-level positions in the file (i.e., outside of
- `defun's or other enclosing forms). This would have disastrous
- consequences to programs that used such top-level macros as `defun*',
- `eval-when', and `defstruct'. To work around this problem, the "CL"
- package patches the Emacs 18 compiler to expand top-level macros. This
- patch will apply to your own macros, too, if they are used in a
- top-level context. The patch will not harm versions of the Emacs 18
- compiler which have already had a similar patch applied, nor will it
- affect the optimizing Emacs 19 byte-compiler written by Jamie Zawinski
- and Hallvard Furuseth. The patch is applied to the byte compiler's
- code in Emacs' memory, *not* to the `bytecomp.elc' file stored on disk.
-
- The Emacs 19 compiler (for Emacs 18) is available from various Emacs
- Lisp archive sites such as `archive.cis.ohio-state.edu'. Its use is
- highly recommended; many of the Common Lisp macros emit code which can
- be improved by optimization. In particular, `block's (whether explicit
- or implicit in constructs like `defun*' and `loop') carry a fair
- run-time penalty; the optimizing compiler removes `block's which are
- not actually referenced by `return' or `return-from' inside the block.
-
- File: cl, Node: Common Lisp Compatibility, Next: Old CL Compatibility, Prev: Efficiency Concerns, Up: Top
-
- Common Lisp Compatibility
- *************************
-
- Following is a list of all known incompatibilities between this package
- and Common Lisp as documented in Steele (2nd edition).
-
- Certain function names, such as `member', `assoc', and `floor', were
- already taken by (incompatible) Emacs Lisp functions; this package
- appends `*' to the names of its Common Lisp versions of these functions.
-
- The word `defun*' is required instead of `defun' in order to use
- extended Common Lisp argument lists in a function. Likewise,
- `defmacro*' and `function*' are versions of those forms which
- understand full-featured argument lists. The `&whole' keyword does not
- work in `defmacro' argument lists (except inside recursive argument
- lists).
-
- In order to allow an efficient implementation, keyword arguments use
- a slightly cheesy parser which may be confused if a keyword symbol is
- passed as the *value* of another keyword argument. (Specifically,
- `(memq :KEYWORD REST-OF-ARGUMENTS)' is used to scan for `:KEYWORD'
- among the supplied keyword arguments.)
-
- The `eql' and `equal' predicates do not distinguish between IEEE
- floating-point plus and minus zero. The `equalp' predicate has several
- differences with Common Lisp; *note Predicates::..
-
- The `setf' mechanism is entirely compatible, except that
- setf-methods return a list of five values rather than five values
- directly. Also, the new "`setf' function" concept (typified by `(defun
- (setf foo) ...)') is not implemented.
-
- The `do-all-symbols' form is the same as `do-symbols' with no
- OBARRAY argument. In Common Lisp, this form would iterate over all
- symbols in all packages. Since Emacs obarrays are not a first-class
- package mechanism, there is no way for `do-all-symbols' to locate any
- but the default obarray.
-
- The `loop' macro is complete except that `loop-finish' and type
- specifiers are unimplemented.
-
- The multiple-value return facility treats lists as multiple values,
- since Emacs Lisp cannot support multiple return values directly. The
- macros will be compatible with Common Lisp if `values' or `values-list'
- is always used to return to a `multiple-value-bind' or other
- multiple-value receiver; if `values' is used without
- `multiple-value-...' or vice-versa the effect will be different from
- Common Lisp.
-
- Many Common Lisp declarations are ignored, and others match the
- Common Lisp standard in concept but not in detail. For example, local
- `special' declarations, which are purely advisory in Emacs Lisp, do not
- rigorously obey the scoping rules set down in Steele's book.
-
- The variable `*gensym-counter*' starts out with a pseudo-random
- value rather than with zero. This is to cope with the fact that
- generated symbols become interned when they are written to and loaded
- back from a file.
-
- The `defstruct' facility is compatible, except that structures are
- of type `:type vector :named' by default rather than some special,
- distinct type. Also, the `:type' slot option is ignored.
-
- The second argument of `check-type' is treated differently.
-
- File: cl, Node: Old CL Compatibility, Next: Porting Common Lisp, Prev: Common Lisp Compatibility, Up: Top
-
- Old CL Compatibility
- ********************
-
- Following is a list of all known incompatibilities between this package
- and the older Quiroz `cl.el' package.
-
- This package's emulation of multiple return values in functions is
- incompatible with that of the older package. That package attempted to
- come as close as possible to true Common Lisp multiple return values;
- unfortunately, it could not be 100% reliable and so was prone to
- occasional surprises if used freely. This package uses a simpler
- method, namely replacing multiple values with lists of values, which is
- more predictable though more noticeably different from Common Lisp.
-
- The `defkeyword' form and `keywordp' function are not implemented in
- this package.
-
- The `member', `floor', `ceiling', `truncate', `round', `mod', and
- `rem' functions are suffixed by `*' in this package to avoid collision
- with existing functions in Emacs 18 or Emacs 19. The older package
- simply redefined these functions, overwriting the built-in meanings and
- causing serious portability problems with Emacs 19. (Some more recent
- versions of the Quiroz package changed the names to `cl-member', etc.;
- this package defines the latter names as aliases for `member*', etc.)
-
- Certain functions in the old package which were buggy or inconsistent
- with the Common Lisp standard are incompatible with the conforming
- versions in this package. For example, `eql' and `member' were
- synonyms for `eq' and `memq' in that package, `setf' failed to preserve
- correct order of evaluation of its arguments, etc.
-
- Finally, unlike the older package, this package is careful to prefix
- all of its internal names with `cl-'. Except for a few functions which
- are explicitly defined as additional features (such as `floatp-safe'
- and `letf'), this package does not export any non-`cl-' symbols which
- are not also part of Common Lisp.
-
-
- The `cl-compat' package
- =======================
-
- The "CL" package includes emulations of some features of the old
- `cl.el', in the form of a compatibility package `cl-compat'. To use
- it, put `(require 'cl-compat)' in your program.
-
- The old package defined a number of internal routines without `cl-'
- prefixes or other annotations. Call to these routines may have crept
- into existing Lisp code. `cl-compat' provides emulations of the
- following internal routines: `pair-with-newsyms', `zip-lists',
- `unzip-lists', `reassemble-arglists', `duplicate-symbols-p',
- `safe-idiv'.
-
- Some `setf' forms translated into calls to internal functions that
- user code might call directly. The functions `setnth', `setnthcdr',
- and `setelt' fall in this category; they are defined by `cl-compat',
- but the best fix is to change to use `setf' properly.
-
- The `cl-compat' file defines the keyword functions `keywordp',
- `keyword-of', and `defkeyword', which are not defined by the new "CL"
- package because the use of keywords as data is discouraged.
-
- The `build-klist' mechanism for parsing keyword arguments is
- emulated by `cl-compat'; the `with-keyword-args' macro is not, however,
- and in any case it's best to change to use the more natural keyword
- argument processing offered by `defun*'.
-
- Multiple return values are treated differently by the two Common
- Lisp packages. The old package's method was more compatible with true
- Common Lisp, though it used heuristics that caused it to report
- spurious multiple return values in certain cases. The `cl-compat'
- package defines a set of multiple-value macros that are compatible with
- the old CL package; again, they are heuristic in nature, but they are
- guaranteed to work in any case where the old package's macros worked.
- To avoid name collision with the "official" multiple-value facilities,
- the ones in `cl-compat' have capitalized names: `Values',
- `Values-list', `Multiple-value-bind', etc.
-
- The functions `cl-floor', `cl-ceiling', `cl-truncate', and
- `cl-round' are defined by `cl-compat' to use the old-style
- multiple-value mechanism, just as they did in the old package. The
- newer `floor*' and friends return their two results in a list rather
- than as multiple values. Note that older versions of the old package
- used the unadorned names `floor', `ceiling', etc.; `cl-compat' cannot
- use these names because they conflict with Emacs 19 built-ins.
-
- File: cl, Node: Porting Common Lisp, Next: Function Index, Prev: Old CL Compatibility, Up: Top
-
- Porting Common Lisp
- *******************
-
- This package is meant to be used as an extension to Emacs Lisp, not as
- an Emacs implementation of true Common Lisp. Some of the remaining
- differences between Emacs Lisp and Common Lisp make it difficult to
- port large Common Lisp applications to Emacs. For one, some of the
- features in this package are not fully compliant with ANSI or Steele;
- *note Common Lisp Compatibility::.. But there are also quite a few
- features that this package does not provide at all. Here are some
- major omissions that you will want watch out for when bringing Common
- Lisp code into Emacs.
-
- * Case-insensitivity. Symbols in Common Lisp are case-insensitive
- by default. Some programs refer to a function or variable as
- `foo' in one place and `Foo' or `FOO' in another. Emacs Lisp will
- treat these as three distinct symbols.
-
- Some Common Lisp code is written in all upper-case. While Emacs
- is happy to let the program's own functions and variables use this
- convention, calls to Lisp builtins like `if' and `defun' will have
- to be changed to lower-case.
-
- * Lexical scoping. In Common Lisp, function arguments and `let'
- bindings apply only to references physically within their bodies
- (or within macro expansions in their bodies). Emacs Lisp, by
- contrast, uses "dynamic scoping" wherein a binding to a variable
- is visible even inside functions called from the body.
-
- Variables in Common Lisp can be made dynamically scoped by
- declaring them `special' or using `defvar'. In Emacs Lisp it is
- as if all variables were declared `special'.
-
- Often you can use code that was written for lexical scoping even
- in a dynamically scoped Lisp, but not always. Here is an example
- of a Common Lisp code fragment that would fail in Emacs Lisp:
-
- (defun map-odd-elements (func list)
- (loop for x in list
- for flag = t then (not flag)
- collect (if flag x (funcall func x))))
-
- (defun add-odd-elements (list x)
- (map-odd-elements (function (lambda (a) (+ a x))) list))
-
- In Common Lisp, the two functions' usages of `x' are completely
- independent. In Emacs Lisp, the binding to `x' made by
- `add-odd-elements' will have been hidden by the binding in
- `map-odd-elements' by the time the `(+ a x)' function is called.
-
- (This package avoids such problems in its own mapping functions by
- using names like `cl-x' instead of `x' internally; as long as you
- don't use the `cl-' prefix for your own variables no collision can
- occur.)
-
- *Note Lexical Bindings::, for a description of the `lexical-let'
- form which establishes a Common Lisp-style lexical binding, and
- some examples of how it differs from Emacs' regular `let'.
-
- * Common Lisp allows the shorthand `#'x' to stand for `(function
- x)', just as `'x' stands for `(quote x)'. In Common Lisp, one
- traditionally uses `#'' notation when referring to the name of a
- function. In Emacs Lisp, it works just as well to use a regular
- quote:
-
- (loop for x in y by #'cddr collect (mapcar #'plusp x)) ; Common Lisp
- (loop for x in y by 'cddr collect (mapcar 'plusp x)) ; Emacs Lisp
-
- When `#'' introduces a `lambda' form, it is best to write out
- `(function ...)' longhand in Emacs Lisp. You can use a regular
- quote, but then the byte-compiler won't know that the `lambda'
- expression is code that can be compiled.
-
- (mapcar #'(lambda (x) (* x 2)) list) ; Common Lisp
- (mapcar (function (lambda (x) (* x 2))) list) ; Emacs Lisp
-
- Lucid Emacs supports `#'' notation starting with version 19.8.
-
- * The "backquote" feature uses a different syntax in Emacs Lisp.
-
- (defmacro foo (v &rest body) `(let ((,v 0)) @,body)) ; Common Lisp
- (defmacro foo (v &rest body) (` (let (((, v) 0)) (@, body))) ; Emacs
-
- * Reader macros. Common Lisp includes a second type of macro that
- works at the level of individual characters. For example, Common
- Lisp implements the quote notation by a reader macro called `'',
- whereas Emacs Lisp's parser just treats quote as a special case.
- Some Lisp packages use reader macros to create special syntaxes
- for themselves, which the Emacs parser is incapable of reading.
-
- The lack of reader macros, incidentally, is the reason behind
- Emacs Lisp's unusual backquote syntax. Since backquotes are
- implemented as a Lisp package and not built-in to the Emacs
- parser, they are forced to use a regular macro named ``' which is
- used with the standard function/macro call notation.
-
- * Other syntactic features. Common Lisp provides a number of
- notations beginning with `#' that the Emacs Lisp parser won't
- understand. For example, `#| ... |#' is an alternate comment
- notation, and `#+lucid (foo)' tells the parser to ignore the
- `(foo)' except in Lucid Common Lisp.
-
- * Packages. In Common Lisp, symbols are divided into "packages".
- Symbols that are Lisp built-ins are typically stored in one
- package; symbols that are vendor extensions are put in another,
- and each application program would have a package for its own
- symbols. Certain symbols are "exported" by a package and others
- are internal; certain packages "use" or import the exported symbols
- of other packages. To access symbols that would not normally be
- visible due to this importing and exporting, Common Lisp provides
- a syntax like `package:symbol' or `package::symbol'.
-
- Emacs Lisp has a single namespace for all interned symbols, and
- then uses a naming convention of putting a prefix like `cl-' in
- front of the name. Some Emacs packages adopt the Common Lisp-like
- convention of using `cl:' or `cl::' as the prefix. However, the
- Emacs parser does not understand colons and just treats them as
- part of the symbol name. Thus, while `mapcar' and `lisp:mapcar'
- may refer to the same symbol in Common Lisp, they are totally
- distinct in Emacs Lisp. Common Lisp programs which refer to a
- symbol by the full name sometimes and the short name other times
- will not port cleanly to Emacs.
-
- Emacs Lisp does have a concept of "obarrays," which are
- package-like collections of symbols, but this feature is not
- strong enough to be used as a true package mechanism.
-
- * Keywords. The notation `:test-not' in Common Lisp really is a
- shorthand for `keyword:test-not'; keywords are just symbols in a
- built-in `keyword' package with the special property that all its
- symbols are automatically self-evaluating. Common Lisp programs
- often use keywords liberally to avoid having to use quotes.
-
- In Emacs Lisp a keyword is just a symbol whose name begins with a
- colon; since the Emacs parser does not treat them specially, they
- have to be explicitly made self-evaluating by a statement like
- `(setq :test-not ':test-not)'. This package arranges to execute
- such a statement whenever `defun*' or some other form sees a
- keyword being used as an argument. Common Lisp code that assumes
- that a symbol `:mumble' will be self-evaluating even though it was
- never introduced by a `defun*' will have to be fixed.
-
- * The `format' function is quite different between Common Lisp and
- Emacs Lisp. It takes an additional "destination" argument before
- the format string. A destination of `nil' means to format to a
- string as in Emacs Lisp; a destination of `t' means to write to
- the terminal (similar to `message' in Emacs). Also, format
- control strings are utterly different; `~' is used instead of `%'
- to introduce format codes, and the set of available codes is much
- richer. There are no notations like `\n' for string literals;
- instead, `format' is used with the "newline" format code, `~%'.
- More advanced formatting codes provide such features as paragraph
- filling, case conversion, and even loops and conditionals.
-
- While it would have been possible to implement most of Common Lisp
- `format' in this package (under the name `format*', of course), it
- was not deemed worthwhile. It would have required a huge amount
- of code to implement even a decent subset of `format*', yet the
- functionality it would provide over Emacs Lisp's `format' would
- rarely be useful.
-
- * Vector constants use square brackets in Emacs Lisp, but `#(a b c)'
- notation in Common Lisp. To further complicate matters, Emacs 19
- introduces its own `#(' notation for something entirely
- different--strings with properties.
-
- * Characters are distinct from integers in Common Lisp. The
- notation for character constants is also different: `#\A' instead
- of `?A'. Also, `string=' and `string-equal' are synonyms in Emacs
- Lisp whereas the latter is case-insensitive in Common Lisp.
-
- * Data types. Some Common Lisp data types do not exist in Emacs
- Lisp. Rational numbers and complex numbers are not present, nor
- are large integers (all integers are "fixnums"). All arrays are
- one-dimensional. There are no readtables or pathnames; streams
- are a set of existing data types rather than a new data type of
- their own. Hash tables, random-states, structures, and packages
- (obarrays) are built from Lisp vectors or lists rather than being
- distinct types.
-
- * The Common Lisp Object System (CLOS) is not implemented, nor is
- the Common Lisp Condition System.
-
- * Common Lisp features that are completely redundant with Emacs Lisp
- features of a different name generally have not been implemented.
- For example, Common Lisp writes `defconstant' where Emacs Lisp
- uses `defconst'. Similarly, `make-list' takes its arguments in
- different ways in the two Lisps but does exactly the same thing,
- so this package has not bothered to implement a Common Lisp-style
- `make-list'.
-
- * A few more notable Common Lisp features not included in this
- package: `compiler-let', `tagbody', `prog', `ldb/dpb',
- `parse-integer', `cerror'.
-
- * Recursion. While recursion works in Emacs Lisp just like it does
- in Common Lisp, various details of the Emacs Lisp system and
- compiler make recursion much less efficient than it is in most
- Lisps. Some schools of thought prefer to use recursion in Lisp
- over other techniques; they would sum a list of numbers using
- something like
-
- (defun sum-list (list)
- (if list
- (+ (car list) (sum-list (cdr list)))
- 0))
-
- where a more iteratively-minded programmer might write one of
- these forms:
-
- (let ((total 0)) (dolist (x my-list) (incf total x)) total)
- (loop for x in my-list sum x)
-
- While this would be mainly a stylistic choice in most Common Lisps,
- in Emacs Lisp you should be aware that the iterative forms are
- much faster than recursion. Also, Lisp programmers will want to
- note that the current Emacs Lisp compiler does not optimize tail
- recursion.
-
-